import {
  ChangeDetectionStrategy,
  Component,
  ContentChild,
  Input,
  OnChanges,
  OnDestroy,
  SimpleChanges,
  TemplateRef,
  ViewChild,
  ViewEncapsulation,
} from '@angular/core';
import { AnimationEvent } from '@angular/animations';
import { Subject } from 'rxjs';
import { InputBoolean } from '../core/api';
import { CollapseLazyDirective } from './collapse.lazy.directive';

@Component({
  selector: 'lv-collapse-panel, [lv-collapse-panel]',
  exportAs: 'lvCollapsePanel',
  template: '<ng-template #bodyTemplate><ng-content></ng-content></ng-template>',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class CollapsePanelComponent implements OnChanges, OnDestroy {
  @Input() lvId: string = null;
  @Input() lvExtra: string | TemplateRef<any> = null;
  @Input() @InputBoolean() lvLoading: boolean = false;
  @Input() @InputBoolean() lvDisabled: boolean = false;
  @Input() @InputBoolean() lvExpanded: boolean = false;
  @Input() lvTitle: string | TemplateRef<any> = 'Title';

  @Input() lvExpandedIcon: string | TemplateRef<any> = null;

  @ViewChild('bodyTemplate', { static: false }) content: TemplateRef<void>;

  @ContentChild(CollapseLazyDirective, { read: TemplateRef, static: false })
  lazyContent: TemplateRef<void>;

  public overflow = 'visible';

  public animationState = 'void';

  public collapsePanelShow = false;

  public expand$ = new Subject<boolean>();

  public viewChange$ = new Subject<void>();

  public openState$ = new Subject<boolean>();

  onAnimationStart(): void {
    this.overflow = 'hidden';
  }

  ngOnDestroy(): void {
    this.openState$.complete();
    this.expand$.complete();
    this.viewChange$.complete();
  }

  onAnimationDone(event: AnimationEvent): void {
    if ((event.fromState === 'show' || event.fromState === 'void') && event.toState === 'hide') {
      this.openState$.next(false);
    }
    this.overflow = 'visible';
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.lvExpanded) {
      this.expand$.next(changes.lvExpanded.currentValue);
    }

    if (changes.lvExpandedIcon?.currentValue) {
      this.lvExpandedIcon = changes.lvExpandedIcon.currentValue;
    }

    this.viewChange$.next();
  }
}
